using System;
using System.Collections.Generic;
using System.Text;
using Evolution.Engine.GUI.Components;
using Microsoft.Xna.Framework;
using Evolution.Engine.Objects;
using Evolution.Engine.Managers;
using Microsoft.Xna.Framework.Graphics;
using Evolution.Engine;
using Microsoft.Xna.Framework.Input;

namespace Evolution.GUI.Components
{
    public class EditBox : Control
    {
        private string _CarectChar = "|";
        private string _Font;
        private Texture2d _Background;
        private Color _Color;
        private bool _Caps = false;
        private int _CaretPos = 0;
        private int _CharactersToShow = 0;
        private int _MaxSize;

        public int MaxSize { get { return _MaxSize; } set { _MaxSize = value; } }
        public Color Color { get { return _Color; } set { _Color = value; } }
        public Texture2d Background { get { return _Background; } set { _Background = value; } }
        public string Font { get { return _Font; } set { _Font = value; } }
        public string CaretChar { get { return _CarectChar; } set { _CarectChar = value; } }

        private int _BlinkTime = 2000;
        private int _BlinkSpeed = 25;
        private int _KeywaitTime = 300;
        private int _KeywaitSpeed = 50;
        private TimeSpan blink = new TimeSpan(0);
        private TimeSpan keyWait = new TimeSpan(0);

        public EditBox(Form parent, string Name, string Text, Vector2 position, Vector2 size, string Font, Color color, int MaxSize)
            : base(parent)
        {
            _Name = Name;
            _Text = Text;
            _Location = position;
            _Size = new SizeF(size.X, size.Y);
            _Font = Font;
            _Color = color;
            _CaretPos = _Text.Length;
            _CharactersToShow = (int)(size.X / FontManager.Instance[Font].MeasureString("X").X) + 2;
            _MaxSize = MaxSize;
            _Background = new Texture2d(_Location, new Vector2(_Size.Width, _Size.Height), "Content/GUI/EditBox/EditBox");
            _Background.LoadContent();
            _Enable = true;

            SetLocation();
        }

        public override void Update(GameTime gameTime)
        {
            blink -= new TimeSpan(_BlinkSpeed);
            if (blink.TotalMilliseconds <= 0)
                blink = new TimeSpan(_BlinkTime);
        }
        public override void Draw(GameTime gameTime)
        {
            _Background.Position = _Location + _Parent.Location;
            _Background.Draw(gameTime);

            Vector2 loc = _Location + _Parent.Location;
            Vector2 size = FontManager.Instance[_Font].MeasureString(_Text);
            float height = size.Y;
            Vector2 caretLoc = _Location + _Parent.Location;

            loc += new Vector2(4, (_Size.Height / 2) - (height / 2) + 1);

            string tmp = "";
            if (_Focus)
                tmp = blink.TotalMilliseconds * 10000 <= _BlinkTime / 2 ? "" : _CarectChar;

            string tmpText = _Text;
            string caretText = tmpText.Insert(_CaretPos, tmp);

            if (_CaretPos >= 0 && _CaretPos <= caretText.Length)
                caretText = caretText.Remove(_CaretPos, caretText.Length - _CaretPos);

            tmpText = tmpText.Substring(
                _CaretPos - _CharactersToShow > 0 ? _CaretPos - _CharactersToShow : 0, 
                _CharactersToShow < tmpText.Length ? _CharactersToShow : tmpText.Length);

            caretText = caretText.Substring(
                _CaretPos - _CharactersToShow > 0 ? _CaretPos - _CharactersToShow : 0,
                _CharactersToShow < caretText.Length ? _CharactersToShow : caretText.Length);

            caretLoc.X += FontManager.Instance[_Font].MeasureString(caretText).X + 5;

            TextManager.Instance.Write(_Font, tmpText, loc, _Color);
            TextManager.Instance.Write(_Font, tmp, caretLoc, _Color);
        }
        public override void SetLocation()
        {
            _Background.Position = _Location + _Parent.Location;
        }
        public override void Resize()
        {
            _Background.Size = new Vector2(_Size.Width, _Size.Height);
        }
        public override void OnKeyDown(KeyEventArgs e)
        {
            if (!_Enable || !_Focus)
                return;

            if (keyWait.TotalMilliseconds <= 0)
            {
                foreach (Keys key in e.Keys)
                {
                    switch (key)
                    {
                        case Keys.A: CharPressed("A", e); break;
                        case Keys.B: CharPressed("B", e); break;
                        case Keys.Back: if (_CaretPos <= _Text.Length && _CaretPos > 0) { _Text = _Text.Remove(_CaretPos - 1, 1); _CaretPos--; }  break;
                        case Keys.Delete: if(_CaretPos < _Text.Length) _Text = _Text.Remove(_CaretPos, 1); break;
                        case Keys.C: CharPressed("C", e); break;
                        case Keys.CapsLock: _Caps = !_Caps; break;
                        case Keys.D: CharPressed("D", e); break;
                        case Keys.D0: CharPressed("0", e); break;
                        case Keys.D1: CharPressed("1", e); break;
                        case Keys.D2: CharPressed("2", e); break;
                        case Keys.D3: CharPressed("3", e); break;
                        case Keys.D4: CharPressed("4", e); break;
                        case Keys.D5: CharPressed("5", e); break;
                        case Keys.D6: CharPressed("6", e); break;
                        case Keys.D7: CharPressed("7", e); break;
                        case Keys.D8: CharPressed("8", e); break;
                        case Keys.D9: CharPressed("9", e); break;
                        case Keys.E: CharPressed("E", e); break;
                        case Keys.End: _CaretPos = _Text.Length; break;
                        case Keys.F: CharPressed("F", e); break;
                        case Keys.G: CharPressed("G", e); break;
                        case Keys.H: CharPressed("H", e); break;
                        case Keys.Home: _CaretPos = 0; break;
                        case Keys.I: CharPressed("I", e); break;
                        case Keys.J: CharPressed("J", e); break;
                        case Keys.K: CharPressed("K", e); break;
                        case Keys.L: CharPressed("L", e); break;
                        case Keys.Left: _CaretPos--; if (_CaretPos < 0) _CaretPos = 0; break;
                        case Keys.Right: _CaretPos++; if (_CaretPos >= _Text.Length) _CaretPos = _Text.Length; break;
                        case Keys.M: CharPressed("M", e); break;
                        case Keys.N: CharPressed("N", e); break;
                        case Keys.NumPad0: CharPressed("0", e); break;
                        case Keys.NumPad1: CharPressed("1", e); break;
                        case Keys.NumPad2: CharPressed("2", e); break;
                        case Keys.NumPad3: CharPressed("3", e); break;
                        case Keys.NumPad4: CharPressed("4", e); break;
                        case Keys.NumPad5: CharPressed("5", e); break;
                        case Keys.NumPad6: CharPressed("6", e); break;
                        case Keys.NumPad7: CharPressed("7", e); break;
                        case Keys.NumPad8: CharPressed("8", e); break;
                        case Keys.NumPad9: CharPressed("9", e); break;
                        case Keys.O: CharPressed("O", e); break;
                        case Keys.P: CharPressed("P", e); break;
                        case Keys.Q: CharPressed("Q", e); break;
                        case Keys.R: CharPressed("R", e); break;
                        case Keys.S: CharPressed("S", e); break;
                        case Keys.Space: CharPressed(" ", e); break;
                        case Keys.T: CharPressed("T", e); break;
                        case Keys.U: CharPressed("U", e); break;
                        case Keys.V: CharPressed("V", e); break;
                        case Keys.W: CharPressed("W", e); break;
                        case Keys.X: CharPressed("X", e); break;
                        case Keys.Y: CharPressed("Y", e); break;
                        case Keys.Z: CharPressed("Z", e); break;
                    }
                }
                keyWait = new TimeSpan(_KeywaitTime);
            }
            else
                keyWait -= new TimeSpan(_KeywaitSpeed);
        }
        private void CharPressed(string character, KeyEventArgs e)
        {
            if (_Text.Length + 1 < _MaxSize)
            {
                string insert =
                    (e.KeyboardState.IsKeyDown(Keys.LeftShift) ||
                     e.KeyboardState.IsKeyDown(Keys.RightShift) ||
                    _Caps)
                        ? character.ToUpper()
                        : character.ToLower();

                _Text = _Text.Insert(_CaretPos, insert);
                _CaretPos++;
            }
        }
        public override void OnMouseUp(MouseEventArgs e)
        {
            if (Bounds.Contains((int)InputManager.Instance.CurrentMouseLocation.X, (int)InputManager.Instance.CurrentMouseLocation.Y) &&
                e.Button == MouseButton.Left)
            {
                _Parent.SetActiveControl(this);
            }
        }
    }
}
